package com.aaron.messenger.data;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.concurrent.ExecutorService;

import com.aaron.messenger.net.ReceiveFileSession;
import com.aaron.messenger.net.SendFileSession;
import com.aaron.messenger.net.NetPort;
import com.aaron.messenger.net.Session;
import com.aaron.messenger.net.Session.SessionStateChangedListener;

class FileTransferManager implements SessionStateChangedListener {

	private static final String TAG = "FileTransferManager";
	
	private ServerThread mServer;
	private ArrayList<SendFileSession> mSendList = new ArrayList<SendFileSession>();
	private ArrayList<ReceiveFileSession> mReceiveList = new ArrayList<ReceiveFileSession>();
	
	private static FileTransferManager  sInstance;
	
	private FileTransferManager() {
	}
	
	public synchronized static FileTransferManager getInstance() {
		if(sInstance == null) {
			sInstance = new FileTransferManager();
		}
		return sInstance;
	}
	
	public void startServer() {
		if(mServer == null) {
			mServer = new ServerThread();
			mServer.start();
		}
	}
	
	public void stopServer() {
		if(mServer != null) {
			try {
				mServer.mServerSocket.close();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			mServer = null;
		}
	}
	
	public void exit() {
		for(SendFileSession session : mSendList) {
			session.stop();
		}
		for(ReceiveFileSession session: mReceiveList) {
			session.stop();
		}
		mSendList.clear();
		mSendList = null;
		
		mReceiveList.clear();
		mReceiveList = null;
		
		stopServer();
		sInstance = null;
	}
	
	public void sendFiles(String target, ArrayList<String> filelist) {
		SendFileSession session = SendFileSession.createSendSession(target, filelist, this);
		session.start();
		mSendList.add(session);
	}
	
	public void cancelSendFileSession(long sessionid) {
		SendFileSession session = findSendFileSession(sessionid);
		if(session != null) {
			mSendList.remove(session);
			session.stop();
		}
	}
	
	public void pauseSendFileSession(long sessionid) {
		SendFileSession session = findSendFileSession(sessionid);
		if(session != null) {
			session.pause();
		}
	}
	
	public void resumeSendFileSession(long sessionid) {
		SendFileSession session = findSendFileSession(sessionid);
		if(session != null) {
			session.resume();
		}
	}
	
	public void cancelReceiveFileSession(long sessionid) {
		ReceiveFileSession session = findReceiveFileSession(sessionid);
		if(session != null) {
			session.stop();
		}
	}
	
	public void pauseReceiveFileSession(long sessionid) {
		ReceiveFileSession session = findReceiveFileSession(sessionid);
		if(session != null) {
			session.pause();
		}
	}
	
	public void resumeReceiveFileSession(long sessionid) {
		ReceiveFileSession session = findReceiveFileSession(sessionid);
		if(session != null) {
			session.resume();
		}
	}
	
	public ArrayList<SendFileSession> getSendSessions() {
		return mSendList;
	}
	
	public ArrayList<ReceiveFileSession> getReceiveSessions() {
		return mReceiveList;
	}

	@Override
	public void onSessionPause(Session session) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void onSessionResume(Session session) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void onSessionStart(Session session) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void onSessionStop(Session session) {
		// TODO Auto-generated method stub
		
	}
	
	private SendFileSession findSendFileSession(long sessionid) {
		for(SendFileSession session:mSendList) {
			if(session.getSessionId() == sessionid) {
				return session;
			}
		}
		return null;
	}
	
	private ReceiveFileSession findReceiveFileSession(long sessionid) {
		for(ReceiveFileSession session:mReceiveList) {
			if(session.getSessionId() == sessionid) {
				return session;
			}
		}
		return null;
	}

	@Override
	public void onSessionFail(Session session) {
		// TODO Auto-generated method stub
		
	}
	
	class ServerThread extends Thread {
		private ServerSocket mServerSocket;
		public void run() {
			try {
				mServerSocket = new ServerSocket(NetPort.FILE_TRANSER_SERVER_PORT);
				while(true) {
					Socket client = mServerSocket.accept();
					ReceiveFileSession session = ReceiveFileSession.createReceiveFileSession(client, FileTransferManager.this);
					mReceiveList.add(session);
					session.start();
				}
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			mServerSocket = null;
		}
	}
}
